﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using SharePointees.EnhancedLookupField.Tools;

namespace SharePointees.EnhancedLookupField.UnitTests
{
    /// <summary>
    /// Summary description for UnitTest1
    /// </summary>
    [TestClass]
    public class CAMLUtilitiesTest
    {
        public CAMLUtilitiesTest()
        {
            //
            // TODO: Add constructor logic here
            //
        }

        private TestContext testContextInstance;

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        #region Additional test attributes
        //
        // You can use the following additional attributes as you write your tests:
        //
        // Use ClassInitialize to run code before running the first test in the class
        // [ClassInitialize()]
        // public static void MyClassInitialize(TestContext testContext) { }
        //
        // Use ClassCleanup to run code after all tests in a class have run
        // [ClassCleanup()]
        // public static void MyClassCleanup() { }
        //
        // Use TestInitialize to run code before running each test 
        // [TestInitialize()]
        // public void MyTestInitialize() { }
        //
        // Use TestCleanup to run code after each test has run
        // [TestCleanup()]
        // public void MyTestCleanup() { }
        //
        #endregion

        [TestMethod]
        public void SingleParameterQuery()
        {
            List<CAMLParameter> parameters = new List<CAMLParameter>();
            parameters.Add(new CAMLParameter(CAMLOperators.Eq, CAMLConditions.None, "FieldsInternalName", "FieldValue"));
            string query = CAMLUtilities.ConstructCAMLQuery(parameters);
            Assert.IsNotNull(query);
            string expectedQuery = "<Where><Eq><FieldRef Name='FieldsInternalName' /><Value Type='Text'>FieldValue</Value></Eq></Where>";
            Assert.IsTrue(expectedQuery.Equals(query));
        }

        [TestMethod]
        public void SingleParameterQueryWithType()
        {
            List<CAMLParameter> parameters = new List<CAMLParameter>();
            parameters.Add(new CAMLParameter(CAMLOperators.Eq, CAMLConditions.None, "FieldsInternalName", "FieldValue", Microsoft.SharePoint.SPFieldType.Number));
            string query = CAMLUtilities.ConstructCAMLQuery(parameters);
            Assert.IsNotNull(query);
            string expectedQuery = "<Where><Eq><FieldRef Name='FieldsInternalName' /><Value Type='Number'>FieldValue</Value></Eq></Where>";
            Assert.IsTrue(expectedQuery.Equals(query));
        }

        [TestMethod]
        public void SingleParameterQueryWithoutCondition()
        {
            List<CAMLParameter> parameters = new List<CAMLParameter>();
            parameters.Add(new CAMLParameter(CAMLOperators.Neq, "FieldsInternalName", "FieldValue"));
            string query = CAMLUtilities.ConstructCAMLQuery(parameters);
            Assert.IsNotNull(query);
            string expectedQuery = "<Where><Neq><FieldRef Name='FieldsInternalName' /><Value Type='Text'>FieldValue</Value></Neq></Where>";
            Assert.IsTrue(expectedQuery.Equals(query));
        }

        [TestMethod]
        public void TwoParametersQuery()
        {
            List<CAMLParameter> parameters = new List<CAMLParameter>();
            parameters.Add(new CAMLParameter(CAMLOperators.Eq, CAMLConditions.And , "FieldsInternalName", "FieldValue"));
            parameters.Add(new CAMLParameter(CAMLOperators.Neq, CAMLConditions.None, "FieldsInternalName", "FieldValue"));
            string query = CAMLUtilities.ConstructCAMLQuery(parameters);
            Assert.IsNotNull(query);
            //Expected CAML :
            //
            //<Where>
            //  <And>
            //      <Eq>
            //          <FieldRef Name='FieldsInternalName' />
            //          <Value Type='Text'>FieldValue</Value>
            //      </Eq>
            //      <Neq>
            //          <FieldRef Name='FieldsInternalName' />
            //          <Value Type='Text'>FieldValue</Value>
            //      </Neq>
            //  </And>
            //</Where>
            string expectedQuery = "<Where><And><Eq><FieldRef Name='FieldsInternalName' /><Value Type='Text'>FieldValue</Value></Eq><Neq><FieldRef Name='FieldsInternalName' /><Value Type='Text'>FieldValue</Value></Neq></And></Where>";
            Assert.IsTrue(expectedQuery.Equals(query));
        }

        [TestMethod]
        public void TwoParametersQueryWithTwoConditions()
        {
            List<CAMLParameter> parameters = new List<CAMLParameter>();
            parameters.Add(new CAMLParameter(CAMLOperators.Eq, CAMLConditions.And, "FieldsInternalName", "FieldValue"));
            parameters.Add(new CAMLParameter(CAMLOperators.Neq, CAMLConditions.Or, "FieldsInternalName", "FieldValue"));
            string query = CAMLUtilities.ConstructCAMLQuery(parameters);
            Assert.IsNotNull(query);
            //Expected CAML :
            //
            //<Where>
            //  <And>
            //      <Eq>
            //          <FieldRef Name='FieldsInternalName' />
            //          <Value Type='Text'>FieldValue</Value>
            //      </Eq>
            //      <Neq>
            //          <FieldRef Name='FieldsInternalName' />
            //          <Value Type='Text'>FieldValue</Value>
            //      </Neq>
            //  </And>
            //</Where>
            string expectedQuery = "<Where><And><Eq><FieldRef Name='FieldsInternalName' /><Value Type='Text'>FieldValue</Value></Eq><Neq><FieldRef Name='FieldsInternalName' /><Value Type='Text'>FieldValue</Value></Neq></And></Where>";
            Assert.IsTrue(expectedQuery.Equals(query));
        }

        [TestMethod]
        public void TwoParametersQueryButFirstParameterWithoutCondition()
        {
            List<CAMLParameter> parameters = new List<CAMLParameter>();
            parameters.Add(new CAMLParameter(CAMLOperators.Eq, CAMLConditions.None, "FieldsInternalName", "FieldValue"));
            parameters.Add(new CAMLParameter(CAMLOperators.Neq, CAMLConditions.Or, "FieldsInternalName", "FieldValue"));
            string query = CAMLUtilities.ConstructCAMLQuery(parameters);
            Assert.IsNotNull(query);
            //Expected CAML :
            //
            //<Where>
            //  <Eq>
            //      <FieldRef Name='FieldsInternalName' />
            //      <Value Type='Text'>FieldValue</Value>
            //  </Eq>
            //</Where>
            string expectedQuery = "<Where><Eq><FieldRef Name='FieldsInternalName' /><Value Type='Text'>FieldValue</Value></Eq></Where>";
            Assert.IsTrue(expectedQuery.Equals(query));
        }

        [TestMethod]
        public void ThreeParametersQueryWithTwoConditions()
        {
            List<CAMLParameter> parameters = new List<CAMLParameter>();
            parameters.Add(new CAMLParameter(CAMLOperators.Eq, CAMLConditions.And, "FieldsInternalName", "FieldValue"));
            parameters.Add(new CAMLParameter(CAMLOperators.Neq, CAMLConditions.None, "FieldsInternalName", "FieldValue"));
            parameters.Add(new CAMLParameter(CAMLOperators.Neq, CAMLConditions.Or, "FieldsInternalName", "FieldValue"));
            string query = CAMLUtilities.ConstructCAMLQuery(parameters);
            Assert.IsNotNull(query);
            //Expected CAML :
            //
            //<Where>
            //  <And>
            //      <Eq>
            //          <FieldRef Name='FieldsInternalName' />
            //          <Value Type='Text'>FieldValue</Value>
            //      </Eq>
            //      <Neq>
            //          <FieldRef Name='FieldsInternalName' />
            //          <Value Type='Text'>FieldValue</Value>
            //      </Neq>
            //  </And>
            //</Where>
            string expectedQuery = "<Where><And><Eq><FieldRef Name='FieldsInternalName' /><Value Type='Text'>FieldValue</Value></Eq><Neq><FieldRef Name='FieldsInternalName' /><Value Type='Text'>FieldValue</Value></Neq></And></Where>";
            Assert.IsTrue(expectedQuery.Equals(query));
        }

        [TestMethod]
        public void NParametersQueryWithNConditions()
        {
            int n = 5;
            List<CAMLParameter> parameters = new List<CAMLParameter>();
            for (int i = 0; i < n; i++)
            {
                if(i%2 == 0)
                    parameters.Add(new CAMLParameter(CAMLOperators.Eq, CAMLConditions.And, "FieldsInternalName", "FieldValue"));
                else
                    parameters.Add(new CAMLParameter(CAMLOperators.Neq, CAMLConditions.Or, "FieldsInternalName", "FieldValue"));
            }
            string query = CAMLUtilities.ConstructCAMLQuery(parameters);
            Assert.IsNotNull(query);
            //Expected CAML :
            //
            //<Where>
            //  <And>
            //      <Eq>
            //          <FieldRef Name='FieldsInternalName' />
            //          <Value Type='Text'>FieldValue</Value>
            //      </Eq>
            //      <Or>
            //          <Neq>
            //              <FieldRef Name='FieldsInternalName' />
            //              <Value Type='Text'>FieldValue</Value>
            //          </Neq>
            //          <And>
            //              <Eq>
            //                  <FieldRef Name='FieldsInternalName' />
            //                  <Value Type='Text'>FieldValue</Value>
            //              </Eq>
            //              <Or>
            //                  <Neq>
            //                      <FieldRef Name='FieldsInternalName' />
            //                      <Value Type='Text'>FieldValue</Value>
            //                  </Neq>
            //                  <Eq>
            //                      <FieldRef Name='FieldsInternalName' />
            //                      <Value Type='Text'>FieldValue</Value>
            //                  </Eq>
            //              </Or>
            //          </And>
            //      </Or>
            //  </And>
            //</Where>

            string expectedQuery = "<Where><And><Eq><FieldRef Name='FieldsInternalName' /><Value Type='Text'>FieldValue</Value></Eq><Or><Neq><FieldRef Name='FieldsInternalName' /><Value Type='Text'>FieldValue</Value></Neq><And><Eq><FieldRef Name='FieldsInternalName' /><Value Type='Text'>FieldValue</Value></Eq><Or><Neq><FieldRef Name='FieldsInternalName' /><Value Type='Text'>FieldValue</Value></Neq><Eq><FieldRef Name='FieldsInternalName' /><Value Type='Text'>FieldValue</Value></Eq></Or></And></Or></And></Where>";
            Assert.IsTrue(expectedQuery.Equals(query));
        }
    }
}
